import axios from 'axios'
import Vue from 'vue'
import { parseCallData } from './callData'
import {
  Notification
} from 'element-ui'
import {
  deepCopy,
  isType,
  hasValue
} from '@/utils'
const duration = 1000 // 消息显示时长
function notifySuccess(message = '', title = '成功') {
  Notification({
    type: 'success',
    message,
    title,
    duration
  })
}
function notifyInfo(message = '', title = '提示') {
  Notification({
    type: 'info',
    message,
    title,
    duration
  })
}
function notifyWarn(message = '', title = '警告') {
  Notification({
    type: 'warning',
    message,
    title,
    duration
  })
}
function notifyError(message = '', title = '错误') {
  Notification({
    type: 'error',
    message,
    title,
    duration
  })
}

export const ajax = axios.create({
  baseURL: process.env.VUE_APP_CALL_PROXY_URL,
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json;charset:UTF-8'
  }
})
ajax.interceptors.request.use(cnf => {
  if (!cnf.url.includes('callService')) {
    cnf.url = '/callService' + cnf.url
  }
  return cnf
}, e => {
  if (e.config.showError) {
    notifyError('请求出错！请重试！')
  }
})
ajax.interceptors.response.use(res => {
  if (res.data.code === 0 || res.data.code === '0') {
    return res.data
  }
  if (res.config.showError) {
    const nowErrorCode = res.data && res.data.code
    notifyError(errorCode[nowErrorCode] || res.data.message)
  }
  return Promise.reject(res.data)
}, e => {
  if (e.config.showError) {
    notifyError('发生错误！')
  }
  return Promise.reject(e)
})

export const request = function(url, data) {
  return ajax.request({
    url,
    method: 'post',
    data: deepCopy(data)
  })
}
/**
 *处理data
 * @params {object} param
 */
function params(param) {
  const t = {}
  if (isType(param, 'Object')) {
    for (const key of Object.keys(param)) {
      if (hasValue(param[key])) {
        t[key] = param[key]
      }
    }
  }
  return t
}
export const assign = Object.assign
// 话务条服务
export class CallProxyService {
  vdnid = '' // 虚拟呼叫中心id
  guid = '' // token
  stop = false // 是否停止轮询
  agentid = '' // 工号
  password = '' // 密码
  phonenum = '' // 分机号
  interval = 600
  status = 0 // 当前状态
  callData={} // 随路数据
  callid = '' // 当前通话id
  callPlatform = '01'
  constructor() {
    this.bus = new Vue()
    // 0"未知。对应CTI平台状态的9。",
    // 1"签入状态。未使用。",
    // 2"签出状态。对应CTI平台状态的0。",
    // 3"示忙状态。对应CTI平台状态的7。",
    // 4"空闲状态。对应CTI平台状态的1。",
    // 5"整理态。对应CTI平台状态的6。",
    // 6"同空闲态。未使用。",
    // 7"通话态。对应CTI平台状态的2、3、4、5。",
    // 8"休息状态。对应CTI平台状态的8。
    this.statusText = {
      0: '未知',
      1: '签入',
      2: '签出',
      3: '示忙',
      4: '示闲',
      5: '整理',
      6: '示闲',
      7: '通话',
      8: '休息'
    }
    // 签出成功停止轮询
    this.on('OnSignOutSuccess', () => this.stopPolling())
  }
  /** 绑定事件
   * @params {string} event 事件名称
   * @params {function} callback 处理函数
   */
  on(event, callback) {
    if (event instanceof Array) {
      for (const e of event) {
        this.bus.$on(e, callback)
      }
    } else {
      this.bus.$on(event, callback)
    }
  }
  /** 绑定once */
  once(event, callback) {
    if (event instanceof Array) {
      for (const e of event) {
        this.bus.$once(e, callback)
      }
    } else {
      this.bus.$once(event, callback)
    }
    // this.bus.$once(event, callback)
  }
  /** 解绑事件
   * @params {string} event 事件名称
   * @params {function} callback 处理函数
   */
  off(event, callback) {
    if (event instanceof Array) {
      for (const e of event) {
        this.bus.$off(e, callback)
      }
    } else {
      this.bus.$off(event, callback)
    }
    // this.bus.$off(event, callback)
  }
  /** 手动触发事件
   * @params {string} event 事件名称
   * @params {any} data 回调参数
   */
  emit(event, data) {
    this.bus.$emit(event, data)
  }
  /** 设置参数
   * @params {number} interval 轮询时间间隔
   * @params {string} agentid 工号
   * @params {string} password 密码
   * @params {string} phonenum 分机号
   */
  setParam(interval, agentid, password, phonenum) {
    this.agentid = agentid || ''
    this.password = password || ''
    this.phonenum = phonenum || ''
    this.interval = interval || 1000 // 轮询间隔时间
    this.stop = false // 是否停止轮询
  }
  /** 自动添加guid和agentid
   * @params {string} url 请求url
   * @params {object} data 请求体
   */
  request(url, data = {}, showError = true) {
    const headers = {}
    if (this.guid !== '') {
      headers.guid = this.guid
    }
    data = deepCopy(data)
    if (!data.agentid) {
      data.agentid = this.agentid
    }
    return ajax.request({
      url,
      method: 'post',
      data: params(data),
      headers,
      showError
    })
  }
  // 停止轮询
  stopPolling() {
    this.stop = true
    clearTimeout(this.timerID)
  }
  // 开始轮询
  startPolling() {
    this.stop = false
    this.eventPolling()
  }
  // 轮训监听坐席事件
  eventPolling() {
    this.timerID = setTimeout(() => {
      this.agentEvent().finally(() => {
        if (!this.stop) {
          this.eventPolling()
        }
      })
    }, this.interval || 200)
  }
  // 监听坐席事件,并分发
  agentEvent() {
    return this.request('/agentEvent', {}, false).then(res => {
      const eventName = res.data.event
      res.data.callData = this.callData // 添加随路数据
      if (eventName) {
        // console.log(eventName)
        this.bus.$emit(eventName, res)
        // if (this.callid) {
        //   this.bus.$emit(`${eventName}-${this.callid}`, res) // 用于通话记录
        // }
      }
    }).finally(r => {
      return Promise.resolve(r)
    })
  }
  // 设置callid
  setCallId(callid) {
    this.callid = callid
  }
  /** 根据状态码获取坐席对应状态
   * @params {number} status 坐席状态
   * @returns {string}
   */
  getStatusText(status) {
    if (status === null || status === undefined) return ''
    return this.statusText[status] || ''
  }
  /** 签入
   * @params {boolean} autoanswer N	是否自动应答，默认为true
   * @params {boolean} autoenteridle N	是否自动进入空闲态，默认为true。
   * @params {boolean} releasephone N	座席挂机后是否进入非长通态：默认为false
   * @params {number} status N	签入后的状态，默认为空闲态。4：空闲，5：整理态。
   * @params {number} agenttype N	签入的座席类型，默认为4。4：pc+phone座席，11：pc+phone视频座席
   */
  signIn(autoanswer, autoenteridle, releasephone, status, agenttype) {
    const data = {
      password: this.password,
      phonenum: this.phonenum,
      autoanswer,
      autoenteridle,
      releasephone,
      status,
      agenttype
    }
    return this.request('/signIn', data).then(res => {
      this.guid = res.data.guid
      this.vdnid = res.data.vdnid
      this.startPolling() // 开始轮询
      return Promise.resolve(res)
    })
  }
  /** 强制签入
   *@params {boolean} autoanswer	N	是否自动应答，默认为true
   *@params {boolean} autoenteridle	N	是否自动进入空闲态，默认为true。
   *@params {boolean} releasephone	N	座席挂机后是否进入非长通态：默认为false
   *@params {number} status	N	签入后的状态，默认为空闲态。4：空闲，5：整理态。
   *@params {number} agenttype	N	签入的座席类型，默认为4。4：pc+phone座席，11：pc+phone视频座席
   *
   */
  forceSignIn(autoanswer, autoenteridle, releasephone, status, agenttype) {
    const data = {
      password: this.password,
      phonenum: this.phonenum,
      autoanswer,
      autoenteridle,
      releasephone,
      status,
      agenttype
    }
    return this.request('/forceSignIn', data).then(res => {
      this.guid = res.data.guid
      this.vdnid = res.data.vdnid
      this.startPolling() // 开始轮询
      return Promise.resolve(res)
    })
  }
  /** 强制签入不绑定话机
   *@params {string} phonenum	N	签入座席使用的电话
   *@params {boolean} autoanswer	N	是否自动应答，默认为true
   *@params {boolean} autoenteridle	N	是否自动进入空闲态，默认为true。
   *@params {boolean} releasephone	N	座席挂机后是否进入非长通态：默认为false
   *@params {number} status	N	签入后的状态，默认为空闲态。4：空闲，5：整理态。
   *@params {number} agenttype	N	签入的座席类型，默认为4。4：pc+phone座席，11：pc+phone视频座席
   *
   */
  forceLoginExWithoutPhone(phonenum, autoanswer, autoenteridle, releasephone, status, agenttype) {
    const data = {
      password: this.password,
      phonenum,
      autoanswer,
      autoenteridle,
      releasephone,
      status,
      agenttype
    }
    return this.request('/forceLoginExWithoutPhone', data).then(res => {
      this.guid = res.data.guid
      this.vdnid = res.data.vdnid
      this.startPolling() // 开始轮询
      return Promise.resolve(res)
    })
  }
  // 签出
  signOut() {
    return this.request('/signOut').then(res => {
      this.guid = ''
      this.stopPolling() // 结束轮询
    })
  }
  // 强制签出，带原因
  forcelogoutwithreason(reason) {
    return this.request('/forcelogoutwithreason', {
      reason
    }).then(res => {
      this.guid = ''
      this.stopPolling() // 结束轮询
    })
  }
  /** 示忙
   * @params {string} 示忙原因码
   */
  sayBusy(reason) {
    // 参数名	数据类型	是否必填	说明
    // agentid	string	Y	坐席工号
    // reason	string	N	示忙原因码（范围200-250，如果为0或者不传递reason，则表示不设置示忙原因码）
    return this.request('/sayBusy', {
      reason
    })
  }
  /** 示闲 */
  sayFree() {
    return this.request('/sayFree')
  }
  /** 呼叫应答 */
  answer() {
    return this.request('/answer')
  }
  /** 挂断呼叫 */
  release() {
    return this.request('/release')
  }
  /** 开始静音 */
  beginMute() {
    return this.request('/beginMute')
  }
  /** 取消静音 */
  endMute() {
    return this.request('/endMute')
  }
  /** 呼叫保持 */
  hold() {
    return this.request('/hold')
  }
  /** 取消保持 */
  unHold(callid) {
    return this.request('/unHold', {
      callid
    })
  }
  /** 外呼
   * @params {string} called Y	被叫号码。内容不可为空，1-24位数字或*或#
   * @params {string} caller Y	主叫号码。内容不可为空，1-24位数字或*或#
   */
  callOut(called, caller) {
    if (typeof called === 'string') {
      called = called.trim()
    }
    return this.request('/callOut', {
      called,
      caller
    })
  }
  /** 内部呼叫
   * @params {string} called Y	被叫号码。内容不可为空，1-24位数字或*或#
   */
  callInner(called) {
    return this.request('/callInner', {
      called
    })
  }
  /** 重新设置技能队列
   * @params {string} autoflag Y	是否自动签入技能标志（true为自动签入座席所配置技能，false为手工签入技能队列， true以外的参数都作为false处理）
   * @params {string} skillid	N	为技能队列ID字符串组，例如1;2;3
   * @params {string} phonelinkage	N	是否话机联动（1是，0否）。
   */
  changeAgentSkill(autoflag, skillid, phonelinkage = 1) {
    return this.request('/changeAgentSkill', {
      autoflag,
      skillid,
      phonelinkage
    })
  }
  /** 进入工作状态 */
  agentEnterWork() {
    return this.request('/agentEnterWork')
  }
  /** 退出工作状态 */
  agentEnterIdle() {
    return this.request('/agentEnterIdle')
  }
  /** 开始录音
   * @params {string} filename N 录音盘符
   */
  beginRecord(filename = null) {
    return this.request('/beginRecord', {
      filename
    })
  }
  /** 停止录音 */
  stopRecord() {
    return this.request('/stopRecord')
  }
  /** 开始放音
   * @params {string} voicepath	Y	文件路径。最大长度100个字符
   * @params {number} startpostion	N	播放文件起始位置
   * @params {number} volumechange	N	放音音量，默认"50"。0-5位数字
   * @params {number} speedchange	 N	放音音速，默认"50"。0-5位数字
   * @params {number} times	N	播放次数，默认为1
   * @params {number} codeformat	N	文件编码格式，目前暂时只支持0：默认为0
   * @params {number} locationid	N	放音节点 默认-1
   */
  beginPlay(voicepath, startpostion, volumechange, speedchange, times, codeformat, locationid) {
    return this.request('/beginPlay', {
      voicepath,
      startpostion,
      volumechange,
      speedchange,
      times,
      codeformat,
      locationid
    })
  }
  /** 停止放音
   */
  stopPlay() {
    return this.request('/stopPlay')
  }
  /** 暂停放音 */
  pausePlay() {
    return this.request('/pausePlay')
  }
  /** 回复放音 */
  resumePlay() {
    return this.request('/resumePlay')
  }
  /** 放音快进
   * @params {number} time	Y	快进的时长（范围为1-9999999999999）
   */
  foreFastPlay(time) {
    return this.request('/foreFastPlay', {
      time
    })
  }
  /** 放音快退
   * @params {number} time	Y	快退的时长（范围为1-9999999999999）
   */
  backFastPlay(time) {
    return this.request('/backFastPlay', {
      time
    })
  }
  /** 呼叫转移
   * @params {number} devicetype Y 转移设备类型，技能队列为1，业务代表为2，IVR设备为3，系统接入码为4，外呼号码为5
   * @params {string} dstaddress Y	转移地址，即转移设备类型对应的设备ID。最大长度24
   * @params {number} mode Y	转移模式，在内部转移的情况下：释放转为0，挂起转为1，成功转为2，指定转为3，合并转为4；在外呼转移的情况下，释放转为1，成功转为2，通话转为3，三方转为4
   * @params {string} callappdata	N	随路数据
   * @params {string} caller N	主叫号码。（内容可为空，为空时为平台默认主叫号码，0-24位数字）。在转外部号码时有效。并且当转出方式为“释放转”时，该参数值无效，即不能携带指定的主叫号码
   * @params {number} mediaability N	媒体能力。（默认为0。0：音频，1：视频。在转外部号码时有效，其他方式的转移根据座席的类型来判断是否带媒体能力）
   */
  transfer(devicetype, dstaddress, mode, callappdata, caller, mediaability) {
    return this.request('/transfer', {
      devicetype,
      dstaddress,
      mode,
      callappdata,
      caller,
      mediaability
    })
  }
  /** 挂断话机 */
  releasePhone() {
    return this.request('/releasePhone')
  }
  /** 发送便签
   * @params { List<int> } agentIds	Y	座席工号。最大100个座席工号
   * @params { string } content	Y	便签内容，最大1024个字符
   */
  sendMessage(agentIds, content) {
    return this.request('/sendMessage', {
      agentIds,
      content
    })
  }
  /** 查询呼叫随路数据 */
  queryCallData() {
    return this.request('/queryCallData').then(res => {
      if (!/\^/.test(res.data.calldata)) {
        try {
          Object.assign(this.callData, JSON.parse(res.data.calldata))
        } catch (e) {
          console.log(e)
        }
      } else {
        try {
          Object.assign(this.callData, parseCallData(res.data.calldata))
        } catch (e) {
          console.log(e)
        }
      }
      return Promise.resolve({
        data: {
          calldata: this.callData
        }
      })
    })
  }
  /** 设置呼叫随路数据
   * @parmas {string} callid	N	呼叫ID
   * @parmas {string} calldata	N	随路数据。最大长度1024
   */
  setCallData(callid, calldata) {
    return this.request('/setCallData', {
      callid,
      calldata
    })
  }
  /** 查询保持列表 */
  holdlist() {
    return this.request('/holdlist')
  }
  /** 查询坐席可用配置技能队列
   * @params {string} workno Y 指定坐席工号
   */
  queryTotalSkills(workno) {
    return this.request('/queryTotalSkills', {
      workno
    })
  }
  /** 查询指定座席详细座席信息
   * @params {string} workno Y 指定坐席工号
   */
  queryAgentInfoByWorkNo(workno) {
    return this.request('/queryAgentInfoByWorkNo', {
      workno
    }).then(res => {
      if (workno === this.agentid) {
        this.status = res.data.status
      }
      return res
    })
  }
  /** 查询所在VDN所有座席当前状态信息 */
  queryAgentInfo() {
    return this.request('/queryAgentInfo')
  }
  /** 查询指定技能队列排队等待呼叫信息
   * @params {number} skillid	Y	被查询技能队列ID
   */
  queryQueueInfo(skillid) {
    return this.request('/queryQueueInfo', {
      skillid
    }, false)
  }
  /** 内部求助
   *@params {string} dstaddress	Y	求助对象，座席工号或技能队列ID
   *@params {number} devicetype	N	求助设备类型，技能队列为1，座席工号为2，默认为2。
   *@params {number} mode	N	求助模式，两方求助为1，三方求助为2，默认为1。
   *@params {string} callappdata	N	需设置的随路数据。内容可为空，最大长度为1024
   */
  consult(dstaddress, devicetype, mode, callappdata) {
    return this.request('/consult', {
      dstaddress,
      devicetype,
      mode,
      callappdata
    })
  }
  /** 三方通话
   *@params {string} callid Y	已经保持住的语音呼叫的callid
   *@params {string} callappdata	N	需设置的随路数据。内容可为空
   */
  confjoin(callid, callappdata) {
    return this.request('/confjoin', {
      callid,
      callappdata
    })
  }
  /** 拆除指定呼叫
   * @params {string} callid Y	待拆除的呼叫callid
   */
  releaseCall(callid) {
    return this.request('/releaseCall', {
      callid
    })
  }
  /** 批量查询指定坐席信息
   * @params {List<number>} agentlist	Y	座席工号列表。数组最大500。
   */
  queryMultiAgentByWorkNo(agentlist) {
    return this.request('/queryMultiAgentByWorkNo', {
      agentlist
    })
  }
  /** 查询配置技能队列座席详细信息
   * @params {List<number>} skillid 技能队列ID
   */
  queryAgentByConfigedSkill(skillid) {
    return this.request('/queryAgentByConfigedSkill', {
      skillid
    })
  }
  /** 查询签入技能队列座席详细信息
   * @params {List<number>} skillid 技能队列ID
   */
  queryAgentBySkill(skillid) {
    return this.request('/queryAgentBySkill', {
      skillid
    })
  }
  /** 查询指定状态的坐席信息
   * @params {string} status	Y	座席状态字符串，以“,”分隔（最大长度20）
   */
  queryAgentStatusByStatus(status) {
    return this.request('/queryAgentStatusByStatus', {
      status
    })
  }
  /** 二次拨号
   * @params {string} number	Y	二次拨号号码
   */
  secondDial(number) {
    return this.request('/secondDial', {
      number
    })
  }
  /** 取消转移 */
  cancelTransfer() {
    return this.request('/cancelTransfer')
  }
  /** 语音技能统计 */
  voiceSkillStatistic() {
    return this.request('/voiceSkillStatistic')
  }
  /** 查询空闲状态坐席信息 */
  idleAgent() {
    return this.request('/idleAgent')
  }
  /** 发送便签
   * @params {List<number>} agentIds	Y	接收者座席工号。最大100个座席工号
   * @params {string} content	Y	便签内容，最大1024个字符

  */
  sendMessageOld(agentIds, content) {
    return this.request('/sendMessageOld', {
      agentIds,
      content
    })
  }
  /** 根据呼叫id查询呼叫信息
   * @params {string} callid 呼叫id
   */
  queryCallInfoByCallId(callid) {
    return this.request('/queryCallInfoByCallId', {
      callid
    })
  }
  /** 释放指定号码连接
   * @params {string} number	Y	待释放的电话号码（1-24位数字）
   */
  releaseSpecificPhone(number) {
    return this.request('/releaseSpecificPhone', {
      number
    })
  }
  /** 查询多个座席人员活动状态的实时监控信息
   * @paraams {List<string>} agentIds Y 坐席工号列表
   */
  queryAgentStatusByAgentids(agentIds) {
    return this.request('/queryAgentStatusByAgentids', {
      agentIds
    })
  }
  // 质检api
  /** 强制签出
   * @params {string} workno	Y	指定坐席工号。
   */
  agentForceOut(workno) {
    return this.request('/agentForceOut', {
      workno
    })
  }
  /** 强制示忙
   * @params {string} workno	Y	指定坐席工号。
   */
  agentForceBusy(workno) {
    return this.request('/agentForceBusy', {
      workno
    })
  }
  /** 强制示闲
   * @params {string} workno	Y	指定坐席工号。
   */
  agentForceIdle(workno) {
    return this.request('/agentForceIdle', {
      workno
    })
  }
  /** 监听
   * @params {string} workno	Y	指定坐席工号。
   */
  listen(workno) {
    return this.request('/listen', {
      workno
    })
  }
  /** 插入
   * @params {string} workno	Y	指定坐席工号。
   */
  insert(workno) {
    return this.request('/insert', {
      workno
    })
  }
  /** 拦截
   * @params {string} workno	Y	指定坐席工号。
   */
  intercept(workno) {
    return this.request('/intercept', {
      workno
    })
  }
  /** 取消侦听和插入
   * @params {string} workno	Y	指定坐席工号。
   */
  cancel(workno) {
    return this.request('/cancel', {
      workno
    })
  }
  /** 切换侦听和插入
   * @params {string} workno	Y	指定坐席工号。
   */
  switch(workno) {
    return this.request('/switch', {
      workno
    })
  }
}
export const cps = new CallProxyService()
process.env.NODE_ENV === 'development' ? window.$cps = cps : ''
export default {
  install(Vue) {
    Object.defineProperty(Vue.prototype, `$callProxyService${cps.callPlatform}`, {
      value: cps
    })
    Object.defineProperty(Vue.prototype, `$cps${cps.callPlatform}`, {
      value: cps
    })
    const notifys = {
      notifySuccess,
      notifyInfo,
      notifyWarn,
      notifyError
    }
    for (const key of Object.keys(notifys)) {
      Object.defineProperty(Vue.prototype, `$${key}`, {
        value: notifys[key]
      })
    }
  }
}

// 错误码
const errorCode = {
  '000-001': '获取Agent事件的方法错误。',
  '000-002': '座席通过URL传递的参数或者地址错误或接口参数不合法，不符合定义。',
  '000-003': '没有权限调用接口。',
  '000-004': '座席正在倒换中。',
  '100-001': '签入参数为空或者不合法。',
  '100-002': '座席已经登录。',
  '100-003': '座席登录的时候抛ResourceUnavailableException或ProviderUnavailableException异常。',
  '100-004': '登录过程中，用户名或者密码错误。',
  '100-005': '登出参数不合法。',
  '100-006': '座席没有登录。',
  '100-007': '座席操作时发生异常，可能是WAS资源错误无法访问或者内部错误产生。',
  '100-008': '座席已经登出。',
  '100-009': '设置座席状态错误。',
  '100-010': '签出时状态错误。',
  '100-011': '签入时参数不合法错误。',
  '100-012': '签入时座席类型错误。',
  '100-013': '绑定座席电话时电话无效。',
  '100-014': '座席签入的电话号码不在配置范围内。',
  '100-015': '座席已经登录。并且不能被强制签出。',
  '100-016': '座席签入时，IP地址无效。',
  '100-017': 'uPortal鉴权失败',
  '110-016': '账号正处于锁定状态。',
  '101-001': '座席没有电话会议。',
  '101-002': '座席不是当前电话会议的主席。',
  '103-001': '黑名单超过最大数',
  '103-002': '新增黑名单失败',
  '103-003': '根据电话号码查询黑名单失败',
  '103-004': '查询所有黑名单失败',
  '103-005': '根据电话号码查询所有黑名单失败',
  '103-006': '刪除所有黑名单失败',
  '103-007': '红名单超过最大数',
  '103-008': '新增红名单失败',
  '103-009': '查询所有红名单失败',
  '103-010': '根据电话号码查询红名单失败',
  '103-011': '更新红名单失败',
  '103-012': '刪除所有红名单失败',
  '103-013': '根据电话号码删除红名单失败',
  '103-014': '座席队列监控超过最大数',
  '103-015': '添加座席队列监控失败',
  '103-016': '移除座席队列监控失败',
  '103-017': '申请无线设备失败',
  '103-018': '查询指定无线设备失败',
  '103-019': '查询所有无线设备失败',
  '103-020': '释放无线设备资源失败',
  '103-021': '查询一周以内早释丢话记录的数量失败',
  '103-022': '查询一周以内早释丢话记录量失败',
  '103-023': '查询骚扰记录失败',
  '103-024': '设置录音信息失败',
  '103-025': '查询录音信息失败',
  '104-001': '未开启录音下载功能',
  '104-002': '用户无质检录音/质检放音权限',
  '104-003': '录音下载失败之文件名不合法',
  '104-004': '录音下载失败之没有配置映射盘符',
  '104-005': '录音下载失败之录音文件不存在',
  '104-006': '录音下载失败之空闲空间不足',
  '104-007': '录音文件格式不支持',
  '104-008': '录音格式系统参数未配置',
  '104-009': '录音转换失败',
  '105-001': 'Redis中未缓存座席信息',
  '105-002': '当前座席正在容灾恢复中',
  '105-003': '已经完成容灾恢复',
  '105-004': '增加座席到容灾恢复队列失败',
  '105-005': '等待容灾恢复超时',
  '106-001': '多媒体开关没有开启',
  '106-002': '发送的消息为空',
  '106-003': '设置的会话数超过最大值，最大值为60',
  '106-004': '会话转接设备类型（devicetype）不支持',
  '106-005': '会话转移内部错误或不支持的转出模式、转出设备类型',
  '106-006': '会话转接时，座席信息空',
  '106-007': '消息内容超过最大值，最大值为2048个字节',
  '106-008': '渠道类型不正确',
  '106-009': '会话转接时，允许携带数据的最大值，最大值为2048个字节',
  '106-010': '会话转接时，转出的模式不支持',
  '106-011': '参数为空',
  '106-012': '超过short类型范围',
  '200-001': '外呼号码错误。',
  '200-002': '应答时没有呼叫错误。',
  '200-003': '静音时没有呼叫错误。',
  '200-004': '静音时呼叫状态错误。',
  '200-005': '连接保持时没有呼叫错误。',
  '200-006': '连接保持时没有保持呼叫错误。',
  '200-007': '取消静音时没有呼叫错误。',
  '200-008': '取消静音时呼叫状态错误',
  '200-009': '报音时没有呼叫错误。',
  '200-010': '三方通话时没有呼叫错误。',
  '200-011': '三方通话时没有保持呼叫错误。',
  '200-012': '呼叫转移时没有呼叫错误。',
  '200-013': '保持时没有呼叫错误。',
  '200-014': '保持时呼叫状态错误。',
  '200-015': '取保持时没有保持呼叫错误。',
  '200-016': '取保持时呼叫状态错误。',
  '200-017': '挂断时无呼叫错误。',
  '200-018': '内部咨询时无呼叫错误。',
  '200-019': '静像时没有呼叫错误。',
  '200-020': '静像时呼叫状态错误。',
  '200-021': '取静像时没有呼叫错误。',
  '200-022': '取静像时呼叫状态错误。',
  '200-023': '释放指定电话号码时没有呼叫错误。',
  '200-024': '释放指定电话号码时不存在此号码呼叫错误。',
  '200-025': '拆除呼叫时没有呼叫错误。',
  '200-026': '呼叫不存在。',
  '210-001': 'URL信息查询不到。',
  '300-001': '查询座席信息无权限错误。',
  '300-002': '查询座席信息无座席信息错误。',
  '300-003': '查询座席班组信息无此座席信息错误。',
  '300-004': '查询座席班组信息无此座席班组信息错误。',
  '400-001': '设置随路数据时无呼叫信息错误。',
  '400-003': '获取保持队列信息时无话务信息。',
  '500-001': '快退时状态错误。',
  '500-002': '快进时状态错误。',
  '500-003': '暂停放音时状态错误。',
  '500-004': '暂停录音时状态错误。',
  '500-005': '继续放音时状态错误。',
  '500-006': '继续录音时状态错误。',
  '500-007': '开始放音时状态错误。',
  '500-008': '开始录音时状态错误。',
  '500-009': '停止放音时状态错误。',
  '500-010': '停止录音时状态错误。',
  '600-001': '查询座席技能队列信息无此座席信息或座席无配置技能错误。',
  '600-002': '查询指定VDN的技能队列信息无队列配置信息。',
  '600-003': '查询座席所在VDN的接入码信息时无配置信息。',
  '600-004': '查询座席所在VDN的IVR信息时无配置信息。',
  '600-005': '查询座席所在VDN的技能队列信息无队列配置信息。',
  '700-001': '会话不存在。',
  '700-002': '调用平台异常。',
  '700-012': '消息发送失败。',
  '700-013': '富媒体文件上传功能没有开启',
  '700-014': '富媒体文件上传时，文件服务器异常',
  '700-015': '富媒体文件上传时，文件后缀或大小不符合要求',
  '700-016': '富媒体文件下载时，文件不存在',
  '700-017': '富媒体文件下载时，无权限下载',
  '700-018': '数据库异常',
  '701-001': '多媒体会议成员为空。',
  '701-002': '查询多媒体会议状态返回空值。',
  '701-003': '创建会议时，创建者或者参与者已经在其他会议中 。',
  '701-004': '邀请与会者时，当前操作者不在会议中。',
  '701-005': '停止会议时，会议不存在或者没有权限操作该会议。',
  '701-006': '创建会议时， 配置台MS IP未配置。',
  '800-001': '配置代理服务为空。',
  '800-002': '配置信息查询异常。',
  '800-003': '默认媒体网关信息不存在。',
  '900-001': '质检操作时发生NOPROVIDER异常 。',
  '900-002': '质检操作时发生没有权限异常。',
  '900-003': '质检操作时发生ResourceUnavailableException异常。',
  '900-004': '质检监视时发生没有座席信息。',
  '900-005': '质检操作时发生状态异常。',
  '900-006': '质检操作时发生录屏的时间参数错异常。',
  '900-007': '质检操作时发生录屏的未加载支持录屏的许可异常。',
  '900-008': '质检操作时发生录屏的平台未知异常。',
  '900-009': '删除质检任务时，未找到任务异常 。',
  '999-001': '服务端的配置文件中配置的WAS URL不正确。',
  '999-002': '查询消息过载。',
  '999-003': '登录数量超过最大值。'
}
